package org.weed.remote.http;

import java.io.File;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.channels.SelectionKey;
import java.nio.channels.ServerSocketChannel;
import java.nio.channels.SocketChannel;
import java.util.concurrent.ExecutorService;

public class HttpConnection {
	public static final int BUFFER_SIZE = 1024;
	public static final int TIMESTAMP_CREATE = 0;
	public static final int TIMESTAMP_REQUEST = 1;
	public static final int TIMESTAMP_RESPONSE = 2;
	
	private SelectionKey key;
	private SocketChannel socketChannel;
	
	private HttpRequest httpRequest;
	private HttpResponse httpResponse;
	private HttpSession session;
	private HttpCookie cookie;
	
	private boolean closed;
	private long createdTime, lastRequestTime, lastResponseTime;
	
	public HttpConnection(SelectionKey serverKey) throws IOException {
		touch(TIMESTAMP_CREATE);		
		ByteBuffer.allocateDirect(BUFFER_SIZE);
		socketChannel = ((ServerSocketChannel) serverKey.channel()).accept();
		socketChannel.configureBlocking(false);
		
		key = socketChannel.register(serverKey.selector(), SelectionKey.OP_READ, this);
		//key.selector().wakeup();
		
		httpRequest = new HttpRequest(this);
		httpResponse = new HttpResponse(this);
		
	}
	
	/**
	 * Update http connection (this) timestamp.
	 */
	public void touch(int timestampType) {
		switch (timestampType) {
		case TIMESTAMP_CREATE:
			createdTime = System.currentTimeMillis();
			break;
		case TIMESTAMP_REQUEST:
			lastRequestTime = System.currentTimeMillis();
			break;
		case TIMESTAMP_RESPONSE:
			lastResponseTime = System.currentTimeMillis();
			break;
		}
	}
	
	public void recvHttpRequest(ExecutorService executor) {
		executor.execute(httpRequest);
	}
	
	public void processHttpRequest() {
		String path = httpRequest.getRequestPath();
		httpResponse.setFile(new File("C:\\Users\\ctang\\Desktop\\Apps" + path));
		registerEvent(HttpConstants.WRITE);
	}
	
	public void sendHttpResponse(ExecutorService executor) {
		executor.execute(httpResponse);
	}
	
	public void registerEvent(int operation) {
		key.interestOps(operation);
		key.selector().wakeup();
	}
	
	public void disconnect() {
		try {
			// must cancel before close, otherwise the key won't get cancelled if
			// socketChannel.close() throws exception
			key.cancel();
			socketChannel.close();
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
	
	//========================================
	//			Getters & Setters
	//========================================
	public SocketChannel getSocketChannel() {
		return socketChannel;
	}
	
	
}
